package com.CST.service.impl.cb;

import com.CST.bo.cb.BdPerformaceBo;
import com.CST.bo.cb.FaVouchersBO;
import com.CST.bo.cb.MonthBO;
import com.CST.common.api.Response;
import com.CST.dto.cb.DateDTO;
import com.CST.entity.cb.*;

import com.CST.mapper.cst.cb.BaseCostMapper;
import com.CST.mapper.cst.cb.JxCostMapper;
import com.CST.mapper.dataplatform.BdPerformanceMapper;
import com.CST.mapper.ecology.JxAssetValueMapper;
import com.CST.mapper.ecology.UfZcnbdbdMapper;
import com.CST.service.cb.IJxCostService;
import com.CST.util.ExcelTransfer;
import com.CST.util.Result;
import com.CST.util.ThreadPoolProxy;
import com.CST.vo.cb.JXInComeVO;
import com.CST.vo.cb.BudgetAssessmentVO;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author qtx
 * @since 2023-05-18
 */
@Service
@Slf4j
public class IJxCostServiceImpl extends ServiceImpl<JxCostMapper, JxCost> implements IJxCostService {


    @Autowired
    private JxCostMapper jxCostMapper;

    @Autowired
    private BdPerformanceMapper bdPerformanceMapper;

    @Autowired
    private UfZcnbdbdMapper ufZcnbdbdMapper;

    private final ExcelTransfer<JxCost> excelTransfer;

    private final ExcelTransfer<BudgetAssessmentVO> excelTransfer1;

    @Autowired
    private ThreadPoolProxy threadPoolProxy;

    public IJxCostServiceImpl(ExcelTransfer<JxCost> excelTransfer, ExcelTransfer<BudgetAssessmentVO> excelTransfer1,
                              ExcelTransfer<JXInComeVO> excelTransferJXInCome) {
        this.excelTransfer = excelTransfer;
        this.excelTransfer1 = excelTransfer1;
        this.excelTransferJXInCome = excelTransferJXInCome;
    }

    private final ExcelTransfer<JXInComeVO> excelTransferJXInCome;

    @Override
    public List<JXInComeVO> queryInComeVos(DateDTO dateDTO) {
        return baseMapper.queryInComeVos(dateDTO);
    }

    @Override
    public Response modifyPerformance(JxCost entity) {

        try {
            boolean b = saveOrUpdate(entity,
                    new QueryWrapper<JxCost>().eq("YEAR", entity.getYear())
                            .eq("MONTH", entity.getMonth())
                            .eq("DEPT_CODE", entity.getDeptCode())
                            .eq("ACCOUNT_CODE", entity.getAccountCode()));
        } catch (Exception e) {
            return Response.error(String.join(":", "添加失败:", e.getMessage()));
        }

        return Response.success("修改成功");
    }


    @Override
    public void exportExcelJXInCome(HttpServletResponse response, DateDTO dateDTO) {
        List<JXInComeVO> jxInComeVOS = baseMapper.queryInComeVos(dateDTO);
        excelTransferJXInCome.exportExcel(response, jxInComeVOS, "考核收入表", "sheet", JXInComeVO.class);
    }

    @Override
    public void importExcelJxCost(MultipartFile file, Integer year, Integer month, String type,
                                  HttpServletResponse response) throws ClassNotFoundException, IOException {
        baseMapper.delete(new QueryWrapper<JxCost>().eq("YEAR", year).eq("MONTH", month).eq("ACCOUNT_CODE", type));
        String excel = excelTransfer.importExcelResult(file, this, list -> {
            ArrayList<JxCost> arrayList = new ArrayList<>();
            list.forEach(e -> {
                if (StringUtils.isNotBlank(e.getAccountCode())) {
                    arrayList.add(e);
                }
            });
            return arrayList;
        });
        failed(response, excel);
    }

    @Override
    public void exportExcelJxCost(HttpServletResponse response) {

    }

    @Override
    public void exportExcelJxCostDemo(HttpServletResponse response, String type) {
        List<BdPerformaceBo> bdPerformaceBos = bdPerformanceMapper.selectDeptCodeAndName(type);
        List<JxCost> jxCostList = new ArrayList<>();
        bdPerformaceBos.forEach(x -> {
            JxCost jxCost = new JxCost();
            jxCost.setDeptCode(x.getDeptCode());
            jxCost.setDeptName(x.getDeptName());
            jxCost.setAccountCode(x.getAccountCode());
            jxCost.setAccountName(x.getAccountName());
            jxCostList.add(jxCost);
        });
        excelTransfer.exportExcel(response, jxCostList, "考核成本", "sheet", JxCost.class);
    }

    @Override
    public List<BudgetAssessmentVO> benefitReportForms(DateDTO dateDTO) throws ExecutionException,
            InterruptedException {
        //创建线程池
        ThreadPoolExecutor executor = threadPoolProxy.threadPoolExecutor();
        //这样的话，内存中只有一份对象引用，每次new 的时候，budgetAssessmentVO对象引用指向不同的budgetAssessmentVO罢了，但是内存中只有一份，这样就大大节省了内存空间了
        BudgetAssessmentVO budgetAssessmentVO = null;
        //转入的资产
        List<BudgetAssessmentVO> transInList = new ArrayList<>();
        //转出的资产
        List<BudgetAssessmentVO> transOutList = new ArrayList<>();
        //计算平均值----总月份(原值除数)
        int finish = 1;
        if (dateDTO.getEndMonth() != null && dateDTO.getStarMonth() != null) {
            finish = dateDTO.getEndMonth() - dateDTO.getStarMonth() + 1;
        }
        //子级科室查询
        List<BudgetAssessmentVO> baseDeptList = selectDeptCodeData(dateDTO);
        //薪酬数据
        List<BudgetAssessmentVO> saralyDataList = this.listsaralyData(dateDTO);
        //需要先查出来查询月份的强制分摊关系，然后将薪酬强制分摊到各个科室
        List<BudgetAssessmentVO> ruleCompelAmortizationList = jxCostMapper.getRuleCompelAmortization(dateDTO);
        //根据开始月与结束月,计算需要查询的月份（这里是不包含院区调拨的固定资产）
        List<CompletableFuture<List<BudgetAssessmentVO>>> completableFutureList = new ArrayList<>();
        List<CompletableFuture<List<BudgetAssessmentVO>>> completableFutureList2 = new ArrayList<>();
        List<CompletableFuture<List<BudgetAssessmentVO>>> completableFutureList3 = new ArrayList<>();
        //如果固定资产查询月份范围
        if (dateDTO.getStarMonth() != null && dateDTO.getEndMonth() != null && dateDTO.getStarYear() != null) {
            //根据范围月份的数量，循环查询，
            for (int i = dateDTO.getStarMonth(); i <= dateDTO.getEndMonth(); i++) {
                int month = i;
                //不包含院区调拨,不包含共用科室的固定资产
                CompletableFuture<List<BudgetAssessmentVO>> assetList =
                        CompletableFuture.supplyAsync(() -> this.selectAssetsData(
                        dateDTO.getStarYear(),
                        month), executor);
                //院区调拨与部门转移的固定资产
                CompletableFuture<List<BudgetAssessmentVO>> allotAssetList =
                        CompletableFuture.supplyAsync(() -> this.selectAssetsData2(
                        dateDTO.getStarYear(),
                        month), executor);
                //科室共用的固定资产
                CompletableFuture<List<BudgetAssessmentVO>> shareAssetList =
                        CompletableFuture.supplyAsync(() -> this.selectAssetsData3(
                        dateDTO.getStarYear(),
                        month), executor);
                //多个子线程addALL进List
                completableFutureList.add(assetList);
                completableFutureList2.add(allotAssetList);
                completableFutureList3.add(shareAssetList);
            }
        }
        int size = completableFutureList.size();
        int size2 = completableFutureList2.size();
        int size3 = completableFutureList3.size();
        CompletableFuture[] sizeall = this.init(size + size2 + size3,
                completableFutureList,
                completableFutureList2,
                completableFutureList3);
        CompletableFuture.allOf(sizeall).join();
        //拿到多线程里的子线程转为list
        HashMap<String, List<?>> assetListThread = this.getListForThread2(completableFutureList);
        HashMap<String, List<?>> allotAssetListThread = this.getListForThread2(completableFutureList2);
        HashMap<String, List<?>> shareAssetListThread = this.getListForThread2(completableFutureList3);
        //固定资产集合
        List<BudgetAssessmentVO> vos = this.getBean(assetListThread, "BudgetAssessmentVO", BudgetAssessmentVO.class);
        //院区借调跟部门转移的固定资产原值
        List<BudgetAssessmentVO> allot = this.getBean(allotAssetListThread,
                "BudgetAssessmentVO",
                BudgetAssessmentVO.class);
        //科室共用的固定资产原值
        List<BudgetAssessmentVO> share = this.getBean(shareAssetListThread,
                "BudgetAssessmentVO",
                BudgetAssessmentVO.class);
        //月份范围
        List<MonthBO> monthBOList = new ArrayList<>();
        MonthBO monthBO = null;
        int x;
        for (x = dateDTO.getStarMonth(); x <= dateDTO.getEndMonth(); x++) {
            monthBO = new MonthBO();
            monthBO.setYear(dateDTO.getStarYear());
            monthBO.setMonth(x);
            monthBOList.add(monthBO);
        }
        //拿到拥有调拨时间的资产编号
        assert allot != null;
        List<String> assetCodeList = allot.stream().map(BudgetAssessmentVO::getAssetCode).collect(Collectors.toList());
        //调拨资产原值信息（卡片资产编码，资产名称，原值，调拨前科室，调拨后科室，调拨前院区，调拨后院区，调拨原因，调拨时间）
        List<BudgetAssessmentVO> transferRecords = ufZcnbdbdMapper.listTransferRecord(assetCodeList);
        //分离院区调拨跟部门调拨
        //调拨院区不相同为院区调拨
        List<BudgetAssessmentVO> yqTrans = transferRecords.stream()
                .filter(t -> !t.getBeforeYq().equals(t.getAfterYq()))
                .collect(Collectors.toList());
        //调拨院区都相同为部门调拨
        List<BudgetAssessmentVO> departmentTrans = transferRecords.stream()
                .filter(t -> t.getBeforeYq().equals(t.getAfterYq()))
                .collect(Collectors.toList());
        //部门调拨分为  转入资产与转出资产
        for (BudgetAssessmentVO item : departmentTrans) {
            BudgetAssessmentVO transInInfo = new BudgetAssessmentVO();
            BudgetAssessmentVO transOutInfo = new BudgetAssessmentVO();
            BeanUtils.copyProperties(item, transInInfo);
            BeanUtils.copyProperties(item, transOutInfo);
            transInList.add(transInInfo);
            transOutList.add(transOutInfo);
        }
        //强制分摊后的人员经费集合
        List<BudgetAssessmentVO> initList = new ArrayList<>();
        BudgetAssessmentVO compelInit = null;
        for (MonthBO item : monthBOList) {
            //过滤出各月的强制分摊关系
            List<BudgetAssessmentVO> compelAmortization = ruleCompelAmortizationList.stream()
                    .filter(t -> t.getMonth().equals(item.getMonth()) && t.getYear().equals(item.getYear()))
                    .collect(Collectors.toList());
            for (BudgetAssessmentVO init : compelAmortization) {
                //拿到需要强制分摊的大科室
                compelInit = new BudgetAssessmentVO();
                //通过科室编号取配强制分摊跟人员经费
                BudgetAssessmentVO salaryinfo = saralyDataList.stream()
                        .filter(t -> t.getDeptCode().equals(init.getPDeptCode()))
                        .findFirst()
                        .orElse(null);
                if (salaryinfo != null) {
                    //赋值强制分摊关系的次级科室
                    compelInit.setDeptCode(init.getDeptCode());
                    //根据系数去分摊人员经费
                    BigDecimal personnelExpenditure = salaryinfo.getPersonnelExpenditure();
                    BigDecimal lastPersonnelExpenditure = personnelExpenditure.multiply(init.getRuleCode());
                    compelInit.setPersonnelExpenditure(lastPersonnelExpenditure);
                    initList.add(compelInit);
                }
                //如果系数是1的情况下，并且salaryinfo=null，就是直接分摊到另一个大科室
                if (init.getRuleCode().equals(new BigDecimal(1))) {
                    compelInit.setDeptCode(init.getDeptCode());
                    //这里可能存在人员经费空的情况，大科到大科
                    if (salaryinfo == null) {
                        compelInit.setPersonnelExpenditure(new BigDecimal(0));
                    } else {
                        compelInit.setPersonnelExpenditure(salaryinfo.getPersonnelExpenditure());
                    }
                    initList.add(compelInit);
                }
            }
            //院区调拨记录处理
            for (BudgetAssessmentVO detail : yqTrans) {
                budgetAssessmentVO = new BudgetAssessmentVO();
                //调拨时间
                LocalDateTime disposeDateTime = detail.getDisposeDate();
                //随便拼一个时分秒
                LocalTime localTime = LocalTime.now();
                //当前查询年月的时间
                LocalDate localDate = LocalDate.of(item.getYear(), item.getMonth(), 1);
                //当前查询年月的时间小于调拨时间时，说明这个资产还在这个科室，当它年月等于的时候，那就说明这个资产发生了调拨
                LocalDateTime selectDate = localDate.atTime(localTime);
                boolean before = selectDate.isBefore(disposeDateTime);
                if (before) {
                    budgetAssessmentVO.setDeptCode(detail.getDeptCode());
                    budgetAssessmentVO.setOriginalValue(detail.getOriginalValue());
                    assert vos != null;
                    vos.add(budgetAssessmentVO);
                }
            }
            //部门调拨 转入
            for (BudgetAssessmentVO detail : transInList) {
                budgetAssessmentVO = new BudgetAssessmentVO();
                //调拨时间
                LocalDateTime disposeDateTime = detail.getDisposeDate();
                //调拨前科室
                String afterDeptCode = detail.getAfterDeptCode();
                int year = disposeDateTime.getYear();
                int month = disposeDateTime.getMonth().getValue();
                //转入的话，比如查询4~6月，这个资产5月操作的，那么4月没有，5月跟6月都要计算原值
                if (item.getYear() == year && item.getMonth() >= month) {
                    budgetAssessmentVO.setDeptCode(afterDeptCode);
                    budgetAssessmentVO.setOriginalValue(detail.getOriginalValue());
                    assert vos != null;
                    vos.add(budgetAssessmentVO);
                }
            }
            //部门调拨 转出
            for (BudgetAssessmentVO detail : transOutList) {
                budgetAssessmentVO = new BudgetAssessmentVO();
                //调拨时间
                LocalDateTime disposeDateTime = detail.getDisposeDate();
                //调拨前科室
                String beforeDeptCode = detail.getBeforeDeptCode();
                int year = disposeDateTime.getYear();
                int month = disposeDateTime.getMonth().getValue();
                //转出的话，比如查询4~6月，这个资产5月操作的，那么只需要计算4月的原值，5月跟6月往后都不计算
                if (item.getYear() == year && item.getMonth() < month) {
                    budgetAssessmentVO.setDeptCode(beforeDeptCode);
                    budgetAssessmentVO.setOriginalValue(detail.getOriginalValue());
                    assert vos != null;
                    vos.add(budgetAssessmentVO);
                }
            }

        }
        //科室共用
        if (share != null) {
            for (BudgetAssessmentVO quark : share) {
                //111820 风湿免疫科住院/130620血管外科住院
                String deptCode = quark.getDeptCode();
                //共用的原值金额
                BigDecimal originalValue = quark.getOriginalValue();
                String[] temp;
                String delimiter = "/";// 指定分割字符
                temp = deptCode.split(delimiter);// 分割字符串
                //数据元素长度
                int length = temp.length;
                //对原值进行平分处理,保留两位小数,不进行四舍五入
                BigDecimal divNum = originalValue.divide(BigDecimal.valueOf(length), 2, RoundingMode.DOWN);
                int tailSize = length - 1;
                // 除去最后一个的情况下
                BigDecimal mulNum = divNum.multiply(BigDecimal.valueOf(tailSize));
                //最后一个有总值减去分值
                BigDecimal subNum = originalValue.subtract(mulNum);
                for (int i = 0; i < temp.length - 1; i++) { //for 循环
                    //拆出来的科室进行赋值,除外最后一个
                    String deptCodeRex = compiles(temp[i]);
                    budgetAssessmentVO = new BudgetAssessmentVO();
                    budgetAssessmentVO.setDeptCode(deptCodeRex);
                    budgetAssessmentVO.setOriginalValue(divNum);
                    assert vos != null;
                    vos.add(budgetAssessmentVO);
                }
                //尾差处理
                String lastDeptCode = compiles(temp[temp.length - 1]);
                budgetAssessmentVO = new BudgetAssessmentVO();
                budgetAssessmentVO.setDeptCode(lastDeptCode);
                budgetAssessmentVO.setOriginalValue(subNum);
                assert vos != null;
                vos.add(budgetAssessmentVO);
            }
        }
        int finalFinish = finish;
        baseDeptList.forEach(item -> {
            //固定资产原值根据科室取配过滤
            List<BudgetAssessmentVO> collect = vos.stream()
                    .filter(t -> item.getDeptCode().equals(t.getDeptCode()))
                    .collect(Collectors.toList());
            if (collect.isEmpty()) {
                item.setOriginalValue(new BigDecimal("0"));
            } else {
                //固定资产原值求和
                BigDecimal sum = collect.stream()
                        .map(BudgetAssessmentVO::getOriginalValue)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                //根据for循环里的finish数量确定他查了几个月，除以取平均数，保留两位小数
                BigDecimal result = sum.divide(BigDecimal.valueOf(finalFinish), 2, RoundingMode.HALF_UP);
                item.setOriginalValue(result);
            }
            //没有强制分摊的科室的人员经费匹配
            BudgetAssessmentVO person = saralyDataList.stream()
                    .filter(p -> p.getDeptCode().equals(item.getDeptCode()))
                    .findFirst()
                    .orElse(null);
            if (person != null) {
                item.setPersonnelExpenditure(person.getPersonnelExpenditure());
            }
            //有强制分摊科室的人员经费匹配
            BudgetAssessmentVO coerce = initList.stream()
                    .filter(p -> p.getDeptCode().equals(item.getDeptCode()))
                    .findFirst()
                    .orElse(null);
            if (coerce != null) {
                item.setPersonnelExpenditure(coerce.getPersonnelExpenditure());
            }
            //不可收费
            BigDecimal storageMaterials = item.getStorageMaterials();
            //人员经费
            BigDecimal personnelExpenditure = new BigDecimal("0");
            personnelExpenditure = item.getPersonnelExpenditure();
            if (personnelExpenditure == null) {
                item.setPersonnelExpenditure(new BigDecimal("0"));
                personnelExpenditure = item.getPersonnelExpenditure();
            }
            //零星支出
            BigDecimal incidentalExpenses = item.getIncidentalExpenses();
            //固定资产折旧
            BigDecimal basicDepreciation = item.getBasicDepreciation();
            //房屋占比费
            BigDecimal housingOccupancyFee = item.getHousingOccupancyFee();
            //调整金额
            BigDecimal adjustmentAmount = item.getAdjustmentAmount();
            //支出合计
            BigDecimal summation = storageMaterials.add(personnelExpenditure, MathContext.DECIMAL32)
                    .add(incidentalExpenses, MathContext.DECIMAL32)
                    .add(basicDepreciation, MathContext.DECIMAL32)
                    .add(housingOccupancyFee, MathContext.DECIMAL32)
                    .add(adjustmentAmount, MathContext.DECIMAL32);
            item.setSummation(summation);
            item.setIsParent("1");
        });
        //处理子级科室得到父级各个项目的合计
        return PDeptCodeData(baseDeptList);
    }

    private String compiles(String deptCode) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(deptCode);
        String str = m.replaceAll("").trim();
        int deptCodeRex = Integer.parseInt(String.valueOf(str));
        return String.valueOf(deptCodeRex);
    }

    //查询固定资产原值月份范围查询(只含共用科室)
    private List<BudgetAssessmentVO> selectAssetsData3(Integer year, Integer monthBO) {
        return jxCostMapper.getAssetInformation3(year, monthBO);
    }

    //查询固定资产原值月份范围查询（包含院区调拨与部门转移）
    private List<BudgetAssessmentVO> selectAssetsData2(Integer year, Integer monthBO) {
        return jxCostMapper.getAssetInformation2(year, monthBO);
    }

    //根据科室-工资对应关系，将人员经费由大科室匹配到住院
    private List<BudgetAssessmentVO> listsaralyData(DateDTO dateDTO) {
        return jxCostMapper.listsaralyData(dateDTO);
    }

    private List<BudgetAssessmentVO> PDeptCodeData(List<BudgetAssessmentVO> baseDeptList) {
        List<BudgetAssessmentVO> parentinfo = jxCostMapper.listParentDeptCode();
        List<BudgetAssessmentVO> result = new ArrayList<>();
        BudgetAssessmentVO info = null;
        for (BudgetAssessmentVO item : parentinfo) {
            info = new BudgetAssessmentVO();
            //根据父科室编号过滤出子集科室中的数据
            List<BudgetAssessmentVO> collect = baseDeptList.stream()
                    .filter(t -> t.getPDeptCode().equals(item.getPDeptCode()))
                    .collect(Collectors.toList());
            //不可收费耗材求和
            BigDecimal storage = collect.stream()
                    .map(BudgetAssessmentVO::getStorageMaterials)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //人员经费求和
            BigDecimal persone = collect.stream()
                    .map(BudgetAssessmentVO::getPersonnelExpenditure)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //零星支出求和
            BigDecimal incide = collect.stream()
                    .map(BudgetAssessmentVO::getIncidentalExpenses)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //固定资产折旧求和
            BigDecimal basic = collect.stream()
                    .map(BudgetAssessmentVO::getBasicDepreciation)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //房屋占比费
            BigDecimal house = collect.stream()
                    .map(BudgetAssessmentVO::getHousingOccupancyFee)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //调整金额求和
            BigDecimal adjust = collect.stream()
                    .map(BudgetAssessmentVO::getAdjustmentAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //资产原值求和
            BigDecimal origin = collect.stream()
                    .map(BudgetAssessmentVO::getOriginalValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //支出合计求和
            BigDecimal summation = collect.stream()
                    .map(BudgetAssessmentVO::getSummation)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            info.setStorageMaterials(storage);
            info.setPersonnelExpenditure(persone);
            info.setIncidentalExpenses(incide);
            info.setBasicDepreciation(basic);
            info.setHousingOccupancyFee(house);
            info.setAdjustmentAmount(adjust);
            info.setSummation(summation);
            info.setOriginalValue(origin);
            info.setPDeptCode(item.getPDeptCode());
            info.setPDeptName(item.getPDeptName());
            //前台页面显示，字段要统一
            info.setDeptCode(item.getPDeptCode());
            info.setDeptName(item.getPDeptName());
            //0是父级
            info.setIsParent("0");
            result.add(info);
            result.addAll(collect);
        }
        return result;
    }


    //查询子级科室不可收费材料费，零星支出，固定资产折旧费，房屋占比费，调整金额
    private List<BudgetAssessmentVO> selectDeptCodeData(DateDTO dateDTO) {
        return jxCostMapper.getInformation(dateDTO);
    }

    //查询固定资产原值月份范围查询 （不含院区调拨，不含共用科室）
    private List<BudgetAssessmentVO> selectAssetsData(Integer year, Integer monthBO) {
        return jxCostMapper.getAssetInformation(year, monthBO);
    }

    @Override
    public void exportExcel(HttpServletResponse response, DateDTO dto) throws ExecutionException, InterruptedException {
        List<BudgetAssessmentVO> budgetAssessmentVOS = benefitReportForms(dto);
        excelTransfer1.exportExcel(response,
                budgetAssessmentVOS,
                "效益考核预算考核成本明细表",
                "sheet",
                BudgetAssessmentVO.class);
    }

    /**
     * 过滤器返回信息
     *
     * @param response  response
     * @throws IOException io失败
     */
    public void failed(HttpServletResponse response, String errorString) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        //设置响应状态码
        response.setStatus(HttpServletResponse.SC_OK);
        //输入响应内容
        PrintWriter writer = response.getWriter();
        String s = JSONArray.toJSON(Result.failed(errorString, 200)).toString();
        writer.write(s);
        writer.flush();
    }


    private HashMap<String, List<?>> getListForThread2(List<CompletableFuture<List<BudgetAssessmentVO>>> list1) {
        List<BudgetAssessmentVO> budgetAssessmentVOList = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            CompletableFuture<List<BudgetAssessmentVO>> future1 = list1.get(i);
            try {
                budgetAssessmentVOList.addAll(future1.get());

            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        HashMap<String, List<?>> result = new HashMap<>();
        result.put("BudgetAssessmentVO", budgetAssessmentVOList);
        return result;
    }

    private <T> List<T> getBean(Map<?, ?> map, String name, Class<T> tClass) {
        Object obj = map.get(name);
        if (obj != null) {
            Class<List> listClass = List.class;
            List<?> cast = listClass.cast(obj);
            List<T> list = new ArrayList<>();
            for (Object o : cast) {
                T converter = this.converter(o, tClass);
                list.add(converter);
            }
            return list;
        }
        return null;
    }

    private CompletableFuture[] init(int maxSize, Collection... list) {
        CompletableFuture[] array = new CompletableFuture[maxSize];
        int size = 0;
        for (Collection future : list) {
            List<CompletableFuture<?>> ls = new ArrayList<>(future);
            for (int i = 0; i < ls.size(); i++) {
                array[size] = ls.get(i);
                size++;
            }
        }
        return array;
    }

    private <T> T converter(Object obj, Class<T> clazz) {
        return clazz.cast(obj);
    }

}

